﻿package frEngine.primitives.object2d
{
    import __AS3__.vec.*;
    import baseEngine.system.*;
    import flash.display.*;
    import flash.geom.*;
    import frEngine.core.*;
    import frEngine.manager.*;
    import frEngine.shader.*;
    import frEngine.shader.filters.*;
    import frEngine.shader.filters.fragmentFilters.*;
    import frEngine.shader.filters.vertexFilters.*;

    public class Scale9GridImg2DEx extends Img2D
    {
        private var uvData:Vector.<Number>;
        private var PositionData:Vector.<Number>;
        private var _splitRow:Vector.<Number>;
        private var _splitCol:Vector.<Number>;
        private var picWidth:int;
        private var picHeight:int;
        private var picOldWidth:int;
        private var picOldHeight:int;
        private var _tran2dx:Number = 0;
        private var _tran2dy:Number = 0;
        private var vertexFilter:Scale9GridFilter;
        private var fragmentFilter:Scale9FragmentFilter;
        private var _transparent:Boolean;
        private var _scale9GridRect:Rectangle;
        private var _gridRect:Rectangle;
        private static var _surf:FrSurface3D;

        public function Scale9GridImg2DEx(param1:String, param2:BitmapData, param3:Boolean, param4:Rectangle)
        {
            this.PositionData = new Vector.<Number>;
            this._splitRow = this.Vector.<Number>([0, 0, 0, 0]);
            this._splitCol = this.Vector.<Number>([0, 0, 0, 0]);
            this.vertexFilter = new Scale9GridFilter();
            this.fragmentFilter = new Scale9FragmentFilter(null);
            this._transparent = param3;
            var _loc_5:* = param2.rect;
            this.picWidth = _loc_5.width;
            this.picHeight = _loc_5.height;
            this._gridRect = param4;
            super(param1, param2, _loc_5, param3, false);
            return;
        }// end function

        override public function setShaderBase(param1:VertexFilter, param2:FragmentFilter) : void
        {
            this._vertexFileter = this.vertexFilter;
            super.setShaderBase(this.vertexFilter, param2);
            return;
        }// end function

        override protected function setTextureFilter(param1, param2:int) : FragmentFilter
        {
            if (!this.fragmentFilter)
            {
                this.fragmentFilter = new Scale9FragmentFilter(Resource3dManager.instance.getTexture3d(param1, param2, this.loadPriority));
            }
            else
            {
                this.fragmentFilter.texture = Resource3dManager.instance.getTexture3d(param1, param2, this.loadPriority);
            }
            this.fragmentFilter.texture.immediatelyUpload();
            return this.fragmentFilter;
        }// end function

        override public function dispose(param1:Boolean = true) : void
        {
            super.dispose(param1);
            this.vertexFilter = null;
            this.fragmentFilter = null;
            return;
        }// end function

        override public function initRect(param1:Rectangle) : void
        {
            rect = param1;
            disposeTexture();
            var _loc_2:* = calculateBgWH(rect.width, rect.height);
            newBgBitmapData = new BitmapData(_loc_2.x, _loc_2.y, this._transparent, 0);
            var _loc_3:* = new Matrix(_loc_2.x / rect.width, 0, 0, _loc_2.y / rect.height);
            newBgBitmapData.draw(oldBgBitmapData, _loc_3);
            this.setMaterial(newBgBitmapData, 0, "Rect3dBg");
            this.picOldWidth = newBgBitmapData.width;
            this.picOldHeight = newBgBitmapData.height;
            this.InitData();
            this.clearSurface();
            this.addSurface(this.surf);
            this.UpdatePosData();
            this.vertexFilter.PositionData = this.PositionData;
            this.material.buildBytes();
            return;
        }// end function

        public function get surf() : FrSurface3D
        {
            var _loc_1:Vector.<Number> = null;
            var _loc_2:Vector.<uint> = null;
            if (!_surf)
            {
                _loc_1 = this.Vector.<Number>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
                _loc_2 = this.Vector.<uint>([4, 1, 0, 5, 1, 4, 5, 2, 1, 6, 2, 5, 6, 3, 2, 7, 3, 6, 8, 5, 4, 9, 5, 8, 9, 6, 5, 10, 6, 9, 10, 7, 6, 11, 7, 10, 12, 9, 8, 13, 9, 12, 13, 10, 9, 14, 10, 13, 14, 11, 10, 15, 11, 14]);
                _surf = new FrSurface3D("quad");
                _surf.addVertexData(FilterName_ID.POSITION_ID, 1, false, null);
                _surf.getVertexBufferByNameId(FilterName_ID.POSITION_ID).vertexVector = _loc_1;
                _surf.indexVector = _loc_2;
                _surf.impUpload = true;
            }
            return _surf;
        }// end function

        override public function draw(param1:Boolean = true, param2:ShaderBase = null) : void
        {
            if (!_scene || !visible)
            {
                return;
            }
            if (_toChange)
            {
                this.UpdatePosData();
                this.vertexFilter.PositionData = this.PositionData;
                _toChange = false;
            }
            this._screenTransform.identity();
            Device3D.worldViewProj.copyFrom(this._screenTransform);
            render.draw(this, this.material);
            return;
        }// end function

        public function SetSize(param1:int, param2:int, param3:Number, param4:Number) : void
        {
            this.width = param1;
            this.height = param2;
            this.x = param3;
            this.y = param4;
            return;
        }// end function

        override public function set width(param1:int) : void
        {
            super.width = param1;
            this.picWidth = param1;
            return;
        }// end function

        override public function set height(param1:int) : void
        {
            super.height = param1;
            this.picHeight = param1;
            return;
        }// end function

        override public function set x(param1:Number) : void
        {
            super.x = param1;
            this._tran2dx = param1;
            return;
        }// end function

        override public function set y(param1:Number) : void
        {
            super.y = param1;
            this._tran2dy = param1;
            return;
        }// end function

        public function set gridRect(param1:Rectangle) : void
        {
            this._gridRect = param1;
            this.InitData();
            return;
        }// end function

        public function get gridRect() : Rectangle
        {
            return this._gridRect;
        }// end function

        private function convertToScale9GridRect() : void
        {
            this._scale9GridRect = this._scale9GridRect || new Rectangle();
            this._scale9GridRect.top = this._gridRect.top;
            this._scale9GridRect.left = this._gridRect.left;
            this._scale9GridRect.right = this.picWidth - this._gridRect.right;
            this._scale9GridRect.bottom = this.picHeight - this._gridRect.bottom;
            return;
        }// end function

        private function InitData() : void
        {
            this.convertToScale9GridRect();
            this.updateSplitDataForIndexUV(this.picOldWidth, this.picOldHeight, this._scale9GridRect.top, this._scale9GridRect.right, this._scale9GridRect.bottom, this._scale9GridRect.left);
            this.uvData = this.Vector.<Number>([this._splitRow[0], this._splitCol[3], this._splitRow[1], this._splitCol[3], this._splitRow[2], this._splitCol[3], this._splitRow[3], this._splitCol[3], this._splitRow[0], this._splitCol[2], this._splitRow[1], this._splitCol[2], this._splitRow[2], this._splitCol[2], this._splitRow[3], this._splitCol[2], this._splitRow[0], this._splitCol[1], this._splitRow[1], this._splitCol[1], this._splitRow[2], this._splitCol[1], this._splitRow[3], this._splitCol[1], this._splitRow[0], this._splitCol[0], this._splitRow[1], this._splitCol[0], this._splitRow[2], this._splitCol[0], this._splitRow[3], this._splitCol[0]]);
            return;
        }// end function

        private function UpdatePosData() : void
        {
            var _loc_1:* = Global3D.scene.viewPort;
            _loc_1 = _loc_1 || new Rectangle(0, 0, 1, 1);
            this.updateSplitData(this._tran2dx + this._offsetX, this._tran2dy + this._offsetY, this.picWidth, this.picHeight, this._scale9GridRect.top, this._scale9GridRect.right, this._scale9GridRect.bottom, this._scale9GridRect.left, _loc_1.width, _loc_1.height);
            this.PositionData.length = 0;
            this.PositionData.push(this._splitRow[0], this._splitCol[0], this.uvData[0], this.uvData[1], this._splitRow[1], this._splitCol[0], this.uvData[2], this.uvData[3], this._splitRow[2], this._splitCol[0], this.uvData[4], this.uvData[5], this._splitRow[3], this._splitCol[0], this.uvData[6], this.uvData[7], this._splitRow[0], this._splitCol[1], this.uvData[8], this.uvData[9], this._splitRow[1], this._splitCol[1], this.uvData[10], this.uvData[11], this._splitRow[2], this._splitCol[1], this.uvData[12], this.uvData[13], this._splitRow[3], this._splitCol[1], this.uvData[14], this.uvData[15], this._splitRow[0], this._splitCol[2], this.uvData[16], this.uvData[17], this._splitRow[1], this._splitCol[2], this.uvData[18], this.uvData[19], this._splitRow[2], this._splitCol[2], this.uvData[20], this.uvData[21], this._splitRow[3], this._splitCol[2], this.uvData[22], this.uvData[23], this._splitRow[0], this._splitCol[3], this.uvData[24], this.uvData[25], this._splitRow[1], this._splitCol[3], this.uvData[26], this.uvData[27], this._splitRow[2], this._splitCol[3], this.uvData[28], this.uvData[29], this._splitRow[3], this._splitCol[3], this.uvData[30], this.uvData[31]);
            return;
        }// end function

        private function updateSplitData(param1:Number, param2:Number, param3:int, param4:int, param5:int, param6:int, param7:int, param8:int, param9:Number, param10:Number) : void
        {
            var _loc_11:* = 0.5 * param9;
            var _loc_12:* = 0.5 * param10;
            this._splitRow[0] = 0;
            this._splitRow[1] = param8 / _loc_11;
            this._splitRow[2] = (param3 - param6) / _loc_11;
            this._splitRow[3] = param3 / _loc_11;
            this._splitCol[0] = 0;
            this._splitCol[1] = param5 / _loc_12;
            this._splitCol[2] = (param4 - param7) / _loc_12;
            this._splitCol[3] = param4 / _loc_12;
            var _loc_13:* = 1 - 2 * param1 / param9;
            var _loc_14:* = 2 * param4 / param10 - 1 + 2 * param2 / param10;
            this._splitRow[0] = this._splitRow[0] - _loc_13;
            this._splitRow[1] = this._splitRow[1] - _loc_13;
            this._splitRow[2] = this._splitRow[2] - _loc_13;
            this._splitRow[3] = this._splitRow[3] - _loc_13;
            this._splitCol[0] = this._splitCol[0] - _loc_14;
            this._splitCol[1] = this._splitCol[1] - _loc_14;
            this._splitCol[2] = this._splitCol[2] - _loc_14;
            this._splitCol[3] = this._splitCol[3] - _loc_14;
            return;
        }// end function

        private function updateSplitDataForIndexUV(param1:int, param2:int, param3:int, param4:int, param5:int, param6:int) : void
        {
            this._splitRow[0] = 0;
            this._splitRow[1] = param6 / param1;
            this._splitRow[2] = (param1 - param4) / param1;
            this._splitRow[3] = param1 / param1;
            this._splitCol[0] = 0;
            this._splitCol[1] = param3 / param2;
            this._splitCol[2] = (param2 - param5) / param2;
            this._splitCol[3] = param2 / param2;
            return;
        }// end function

    }
}
